import { EventType } from './EventType';

/**
 * EventManager 事件管理者
 * 通过观察者模式，利用event事件通知，串联系统各个模块的通信。
 * EventManager则是单例模式存在，所有event事件管理者，其提供事件注册、取消、分发等功能。
 * 使用帮助请参考scene/test_EventManager
 */
export class EventManager {
    static Instance: EventManager = new EventManager();

    // 依托于cc.EventTarget来实现event的注册、分发等功能
    private _managerImpl: cc.EventTarget = new cc.EventTarget();

    /**
     * !#en
     * Destroy all callbackInfos.
     * !#zh
     * 销毁记录的事件
     *
     * @method clear
     */
    clear(): void {
        // remove all callback
        this._managerImpl.clear();
    }

    /**
     * 通过事件名发送自定义事件
     * @param type event type
     * @param arg1 First argument
     * @param arg2 Second argument
     * @param arg3 Third argument
     * @param arg4 Fourth argument
     * @param arg5 Fifth argument
     */
    dispatch(type: EventType | string, arg1?: unknown, arg2?: unknown, arg3?: unknown, arg4?: unknown, arg5?: unknown): void {
        this._managerImpl.emit(type, arg1, arg2, arg3, arg4, arg5);
    }

    /**
     * 注册事件目标的特定事件类型回调
     * @param type event type
     * @param cb
     * @param target
     */
    on(type: EventType | string, cb, target): void {
        this._managerImpl.on(type, cb, target);
    }

    /**
     * 注册事件目标的特定事件类型回调，回调会在第一时间被触发后删除自身
     * @param type event type
     * @param cb
     * @param target
     */
    once(type: EventType | string, cb, target): void {
        this._managerImpl.once(type, cb, target);
    }

    /**
     * 删除之前用同类型，回调，目标或 useCapture 注册的事件监听器，如果只传递 type，将会删除 type 类型的所有事件监听器。
     * @param type
     * @param cb
     * @param target
     */
    off(type: EventType | string, cb?, target?): void {
        this._managerImpl.off(type, cb, target);
    }

    /**
     * 在当前 EventTarget 上删除指定目标（target 参数）注册的所有事件监听器
     * @param target
     */
    targetOff(target): void {
        this._managerImpl.targetOff(target);
    }
}
